home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 2 / The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO / door / twview93.zip / VIEWDOS.INC < prev   
Text File  |  1992-03-11  |  15KB  |  511 lines

  1. {VIEWDOS.INC}
  2.  
  3. const
  4.   xmax = 470;
  5.   ymax = 270;
  6.   XDimMax  = 20;
  7.   YDimMax  = 15;
  8.   xoffset  = 10;
  9.   yoffset  = -2;
  10.  
  11. type
  12.   Vertex = record
  13.              sectorNum: integer;  { 0 if not in use }
  14.            end;
  15.   XIndex = 1..XDimMax;
  16.   YIndex = 1..YDimMax;
  17.   Screen = array [XIndex, YIndex ] of Vertex;
  18.   Pair   = record
  19.              visible : boolean;
  20.              row : XIndex;
  21.              col : YIndex;
  22.            end;
  23.   SectorToScreen = array [ sector ] of pair;
  24.  
  25.  
  26. procedure View;
  27. var
  28.   Grid      : screen;
  29.   OnScreen  : SectorToScreen;
  30.   XMax      : integer;
  31.   XDim      : XIndex;
  32.   XLength   : integer;
  33.   YMax      : integer;
  34.   YDim      : YIndex;
  35.   YLength   : integer;
  36.   abort,
  37.   GotDistances : boolean;
  38.   BaseSector: sector;
  39.  
  40. {$I svga.inc }
  41.  
  42. function xpixel( i,j : integer ) : integer;
  43. begin
  44.   if not odd( j ) then
  45.     xpixel := (2 * i - 1) * XLength
  46.   else
  47.     xpixel := 2 * i * XLength;
  48. end;
  49.  
  50. function ypixel( i,j : integer ) : integer;
  51. begin
  52.   ypixel := (2 * j - 1) * Ylength;
  53. end;
  54.  
  55. procedure Tag( var STS : sectorToScreen;
  56.                var scr : screen;
  57.                    num : sector;
  58.                   irow : XIndex;
  59.                   jcol : YIndex );
  60. { put sector num into screen scr at irow, jcol; update sts accordingly }
  61. begin
  62.   if sts[ num].visible then
  63.     writeln('sector ', num, ' already placed before Tag!')
  64.   else if scr[ irow, jcol ].sectorNum <> 0 then
  65.     writeln('row ', irow, ', col ', jcol, ' already in use!')
  66.   else
  67.     begin
  68.       with STS[ num ] do
  69.         begin
  70.           visible := true;
  71.           row     := irow;
  72.           col     := jcol;
  73.         end; {with}
  74.       scr[ irow, jcol ].SectorNum := num;
  75.     end; {else}
  76. end; {tag}
  77.  
  78. procedure CheckOffspring( var P : Queue; where : sector; maxDist : integer);
  79. { Check all sectors from "where" to see if they should be pushed
  80. onto the Queue }
  81. var
  82.   t : warpIndex;
  83. begin
  84.   with space.sectors[ where ] do
  85.     if number > 0 then
  86.       for t := 1 to number do
  87.         if (not OnScreen[ data[ t ] ].visible) and
  88.            (Distances[ data[t] ].d <= maxDist)    then
  89.           enqueue( P, where, data[ t ] );
  90. end; {check offspring}
  91.  
  92. procedure GoDirection( d : integer;
  93.                    var Row   : XIndex;
  94.                    var Col   : YIndex);
  95. { 0 is upleft, 1 left, 2 downleft, 3 downright, etc mod 6 }
  96. begin
  97.   d := abs( d ) mod 6;
  98.   if odd( Col ) then
  99.     case d of
  100.       0 : begin
  101.             if Col > 1 then col := col - 1;
  102.             if Row < XDim then row := row + 1;
  103.           end;
  104.       1 : if Row < XDim then row := row + 1;
  105.       2 : begin
  106.             if Col < YDim then col := col + 1;
  107.             if Row < XDim then row := row + 1;
  108.           end;
  109.       3 : if Col < YDim then col := col + 1;
  110.       4 : if row > 1 then row := row - 1;
  111.       5 : if Col > 1 then col := col - 1;
  112.     end {case}
  113.   else
  114.     case d of
  115.     0 : if Col > 1 then col := col - 1;
  116.     1 : if Row < XDim then row := row + 1;
  117.     2 : if Col < YDim then col := col + 1;
  118.     3 : begin
  119.           if Col < YDim then col := col + 1;
  120.           if Row > 1 then row := row - 1;
  121.         end;
  122.     4 : if Row > 1 then row := row - 1;
  123.     5 : begin
  124.           if Col > 1 then col := col - 1;
  125.           if Row > 1 then row := row - 1;
  126.         end;
  127.     end; {case}
  128. end;
  129.  
  130. procedure seek( var freerow : Xindex; var freecol : Yindex; home : sector );
  131. const
  132.   MaxTries = 100;
  133. var
  134.   one, two, three, n : integer;
  135. { Trying to find a home for the new guy, close to the home sector.
  136. one, two, and three will be random directions to try (of radius 1, 2, and
  137. 3).  When we are successful, we just break out of the procedure, hopefully
  138. returning a freerow and freecol. }
  139. begin
  140.   one := random( 6 );
  141.   for one := one to one + 5 do { from random start, advance 5 positions }
  142.     begin
  143.       freerow := OnScreen[ home ].row;
  144.       freecol := OnScreen[ home ].col;
  145.       GoDirection( one, freerow, freecol );
  146.       if grid[ freerow, freecol ].SectorNum = 0 then
  147.         exit;
  148.     end; {one}
  149.   one := random( 6 );
  150.   two := random( 6 );
  151.   for one := one to one + 5 do
  152.     for two := two to two + 5 do
  153.       begin
  154.         freerow := OnScreen[ home ].row;
  155.         freecol := OnScreen[ home ].col;
  156.         GoDirection( one, freerow, freecol );
  157.         GoDirection( two, freerow, freecol );
  158.         if grid[ freerow, freecol ].SectorNum = 0 then
  159.           exit;
  160.       end; {one two}
  161.   one := random( 6 );
  162.   two := random( 6 );
  163.   three := random( 6 );
  164.   for one := one to one + 5 do
  165.     for two := two to two + 5 do
  166.       for three := three to three + 5 do
  167.         begin
  168.           freerow := OnScreen[ home ].row;
  169.           freecol := OnScreen[ home ].col;
  170.           GoDirection( one, freerow, freecol );
  171.           GoDirection( two, freerow, freecol );
  172.           GoDirection( three, freerow, freecol );
  173.           if grid[ freerow, freecol ].SectorNum = 0 then
  174.             exit;
  175.         end; {one two three}
  176.   writeln('couldn''t place anything near ', home );
  177.   n := 0;
  178.   repeat
  179.     freerow := random( xdim ) + 1;
  180.     freecol := random( ydim ) + 1;
  181.     n := n + 1;
  182.   until (n = MaxTries) or (grid[ freerow, freecol ].sectorNum = 0);
  183. end; {seek}
  184.  
  185. procedure FindHome( var Grid : screen;
  186.                     var Showing : SectorToScreen;
  187.                         home, near : sector );
  188. { This is an interesting bit: given the home sector, find an open slot
  189. in the Grid to place the near sector. }
  190. var
  191.   basedir : integer;
  192.   baserow : XIndex;
  193.   basecol : YIndex;
  194. begin
  195. {  writeln('Trying to find a home for ', near, ' close to ', home );
  196.   writeln('starting at ', showing[ home ].row, showing[ home ].col ); }
  197.   seek( baserow, basecol, home );
  198.   if grid[ baserow, basecol ].SectorNum <> 0 then
  199.     writeln('Seek Failed!')
  200.   else
  201.     Tag( Showing, Grid, near, baserow, basecol );
  202. {  writeln('chose ', baserow, ' ', basecol );
  203.   readln; }
  204. end;
  205.  
  206. procedure DistanceSortedQueueLoad( var q : queue; max : integer );
  207. { Load all pairs (parent, offspring) from the distance array whose distance
  208. is less than max, but do so in priority order sorted by distance. }
  209. var
  210.   r : integer;
  211.   sec : sector;
  212. begin
  213.   for r := 1 to max do
  214.     for sec := 1 to maxSector do
  215.       if distances[sec].d = r then
  216.         enqueue( q, distances[sec].s, sec );
  217. end; {DistanceSortedQueueLoad}
  218.  
  219. procedure PlaceSectors( var Grid  : screen;
  220.                         var Showing : SectorToScreen;
  221.                         var maxDist : integer;
  222.                         var BaseSect : sector );
  223. var
  224.   PlaceMe : Queue;
  225.   daddy, sonny : sector;
  226. begin
  227.   Tag( showing, Grid, baseSect, XDim div 2, YDim div 2 ); { put first in center}
  228.   PlaceMe.front := 0;
  229.   DistanceSortedQueueLoad( PlaceMe, maxdist );
  230.   While PlaceMe.front <> 0 do
  231.     begin
  232.       serve( PlaceMe, daddy, sonny );
  233.       if showing[ daddy ].visible then
  234.         FindHome( Grid, Showing, daddy, sonny );
  235.     end; {while}
  236. end; {while}
  237.  
  238. procedure InitSectorToScreen( var s : SectorToScreen );
  239. var
  240.   n : sector;
  241. begin
  242.   for n := 1 to MaxSector do
  243.     s[ n ].visible := false;
  244. end;
  245.  
  246. procedure InitScreen( var s : Screen );
  247. var
  248.   r : XIndex;
  249.   c : YIndex;
  250. begin
  251.   for r := 1 to XDim do for c := 1 to YDim do
  252.     s[ r, c ].sectorNum := 0;
  253. end;
  254.  
  255.  
  256. procedure FillGrid( var Grid : screen;
  257.                     var Showing : SectorToScreen;
  258.                     var Distances : distanceArray;
  259.                     var HaveDists : boolean;
  260.                     var sn : sector;
  261.                     var abort : boolean );
  262. { Choose a sector, and fill Distances with distance to that sector,
  263. as well as Showing and Grid based on nearby vertices. }
  264. var
  265.   maxD : integer;
  266.   ch   : char;
  267. begin
  268.   InitSectorToScreen( Showing );
  269.   InitScreen( Grid );
  270.   if not HaveDists then
  271.     begin
  272.       repeat
  273.         write('Starting at which sector? ');
  274.         readln( sn );
  275.         if sn = 0 then
  276.           begin
  277.             writeln('Aborting...');
  278.             abort := true;
  279.             exit;
  280.           end; {if}
  281.         if space.sectors[ sn ].number = 0 then
  282.           writeln('You have never visited ', sn );
  283.       until space.sectors[ sn ].number > 0;
  284.       write( 'Sectors <L>eaving ', sn, ', sectors coming <T>oward ', sn, ', or <B>oth? ');
  285.       readln( ch );
  286.       if ch in ['l','L'] then
  287.         TwoWayDistances( sn, distances, false, true )
  288.       else if ch in ['t','T'] then
  289.         TwoWayDistances( sn, distances, true, false )
  290.       else
  291.         TwoWayDistances( sn, distances, true, true );
  292.       HaveDists := true;
  293.     end; {if}
  294.   write( 'Max distance to include? ');
  295.   readln( maxD );
  296.   writeln( 'Total of ', CountDist(Distances, maxD), ' at distance at most ', MaxD );
  297.   PlaceSectors( Grid, Showing, maxD, sn );
  298. end; {FillGrid}
  299.  
  300. function PortColor( g : stuff; mono : boolean ) : word;
  301. begin
  302.   if (GetMaxColor = 1) or mono then
  303.     PortColor := 0
  304.   else
  305.     case g of
  306.       NotAPort : PortColor := Black;
  307.              0 : PortColor := Blue;
  308.              1 : PortColor := Green;
  309.              2 : PortColor := Cyan;
  310.              3 : PortColor := LightRed;
  311.              4 : PortColor := Magenta;
  312.              5 : PortColor := LightBlue;
  313.              6 : PortColor := LightGreen;
  314.              7 : PortColor := LightCyan;
  315.              8 : PortColor := Yellow;
  316.       else
  317.         PortColor := black;    {shouldn't happen...}
  318.     end; {case}
  319. end; {PortColor}
  320.  
  321. function  SectorColor( s : sector; mono : boolean ) : word;
  322. begin
  323.   if GetMaxColor = 1 then {monochrome}
  324.     SectorColor := 1
  325.   else  {not monochrome }
  326.     with space.sectors[s] do
  327.       if number = 0 then
  328.         if mono then
  329.           SectorColor := White
  330.         else
  331.           SectorColor := Yellow
  332.       else if etc and HasFighters <> 0 then
  333.         SectorColor := White
  334.       else if porttype = NotAPort then
  335.         SectorColor := LightGray
  336.       else if PortColor( porttype, mono ) < LightBlue then
  337.         SectorColor := LightGray
  338.       else
  339.         SectorColor := black;
  340. end; {SectorColor}
  341.  
  342. procedure CircleSector( x : XIndex; y : YIndex; s : sector; mono : boolean );
  343. var
  344.   r, c, xradius : integer;
  345.   xasp, yasp    : word;
  346.   ColorUsed     : word;
  347.   Pporttype     : string;
  348. begin
  349.   r := xpixel( x, y );
  350.   c := ypixel( x, y );
  351.   GetAspectRatio( xasp, yasp );
  352.   xradius := round( yasp/xasp * ylength/2);
  353.   SetLineStyle( SolidLn, 0, NormWidth );
  354.   if space.sectors[s].number = 0 then
  355.     SetColor( Black )
  356.   else
  357.     SetColor( SectorColor( s , mono) );
  358.   SetFillStyle( SolidFill, PortColor( space.sectors[s].porttype, mono ) );
  359.   if space.sectors[s].porttype = NotAPort then
  360.     FillEllipse( r, c, xradius, ylength div 2 )
  361.   else
  362.     begin
  363.       bar( r - xradius, c - ylength div 2, r + xradius, c + ylength div 2 );
  364.       rectangle( r - xradius, c - ylength div 2,
  365.                  r + xradius, c + ylength div 2 );
  366.     end; {port}
  367.   if space.sectors[s].number = 1 then
  368.     circle( r, c, xradius + 3 );
  369.   SetColor( SectorColor( s, mono) );
  370.   if (not mono) or (space.sectors[s].porttype = NotAPort) then
  371.     outTextXY( r, c, str( s, 3 ) )
  372.   else {use mono display}
  373.     begin
  374.       outtextXY(r, c-3, str(s,3));
  375.       outtextXY(r, c+7, status(space.sectors[s].porttype) );
  376.     end; {else}
  377.   if space.sectors[s].etc and SpaceLane <> Nothing then
  378.     begin
  379.       SetLineStyle( SolidLn, 0, NormWidth );
  380.       MoveTo( r - xradius,  c - ylength div 2 );
  381.       LineTo( r + xradius, c + ylength div 2 );
  382.     end; {if}
  383. end;
  384.  
  385. procedure ConnectVertices( i1, i2 : XIndex; j1, j2 : YIndex;
  386.                            TwoWay : boolean );
  387. var
  388.   n,
  389.   x1, y1, x2, y2 : integer;
  390.   dist : real;
  391. begin
  392.   x1 := xpixel( i1, j1 );
  393.   y1 := ypixel( i1, j1 );
  394.   x2 := xpixel( i2, j2 );
  395.   y2 := ypixel( i2, j2 );
  396.   if TwoWay then
  397.     SetLineStyle( SolidLn, 0, NormWidth )
  398.   else
  399.     SetLineStyle( DashedLn, 0, ThickWidth );
  400.   dist := sqrt( abs(i2-i1) + abs(j2-j1));
  401.   if (dist <= 1.5) or (dist >=9) then
  402.     n := 0
  403.   else
  404.     n := round(3*dist);
  405.  
  406.   MoveTo( x1+n, y1+n );
  407.   LineTo( x2+n, y2+n );
  408. end;
  409.  
  410. procedure DrawGrid( var G : screen; STS : SectorToScreen );
  411. var
  412.   i : XIndex;
  413.   j : YIndex;
  414.   t : WarpIndex;
  415.   temp : integer;
  416. begin
  417.   for i := 1 to XDim do
  418.     for j := 1 to YDim do
  419.       if G[ i, j ].sectorNum <> 0 then
  420.         with G[ i, j ] do
  421.           with space.sectors[ sectorNum ] do if number > 0 then
  422.             for t := 1 to number do
  423.               if STS[ data[ t ] ].visible then
  424.                 ConnectVertices( i, STS[data[t] ].row, j, STS[data[t]].col,
  425.                                  IsWarp( data[t], sectorNum ) );
  426.   for i := 1 to XDim do
  427.     for j := 1 to YDim do
  428.       if G[ i, j ].sectorNum <> 0 then
  429.           CircleSector( i, j, G[i,j].sectorNum, mono );
  430. end;
  431.  
  432. {$I initgrph.inc }
  433.  
  434. procedure GetDimensions( var x : XIndex; var xl : integer;
  435.                          var y : YIndex; var yl : integer );
  436. const
  437.   whitespace : set of char = [' ', #9, #10, #13 ];
  438. var
  439.   line : string;
  440.   ok   : boolean;
  441.   tempx, tempy,
  442.   position : integer;
  443. begin
  444.   ok := false;
  445.   repeat
  446.     write('Max dimensions? [', XDimMax, ' by ', YDimMax, ']  ');
  447.     readln( line );
  448.     if line = '' then
  449.       begin
  450.         ok := true;
  451.         x := XDimMax * 2 div 3;
  452.         y := YDimMax * 2 div 3;
  453.       end
  454.     else
  455.       begin
  456.         position := 1;
  457.         tempx := 0;
  458.         while (position <= length( line )) and
  459.               (line[position] in ['0'..'9']) do
  460.           begin
  461.             tempx := 10 * tempx + ord( line[ position ] ) - ord( '0' );
  462.             inc( position );
  463.           end; {while}
  464.         inc( position );
  465.         while (position <= length( line ) ) and
  466.               (line[position] in whitespace) do
  467.           inc( position );
  468.         tempy := 0;
  469.         while (position <= length( line )) and
  470.               (line[position] in ['0'..'9']) do
  471.           begin
  472.             tempy := 10 * tempy + ord( line[position] ) - ord('0');
  473.             inc( position );
  474.           end; {while}
  475.         ok := (tempx>0) and (tempx<=XDimMax) and (tempy>0) and (tempy<=YDimMax);
  476.         if ok then
  477.           begin
  478.             x := tempx;
  479.             y := tempy;
  480.           end {if}
  481.         else
  482.           begin
  483.             writeln('I don''t understand ', line );
  484.             writeln('Please give two integers separated by a space.');
  485.           end; {else}
  486.       end; {else}
  487.   until ok;
  488.   InitGraphics;
  489.   XMax := GetMaxX;
  490.   YMax := GetMaxY;
  491.   closeGraph;
  492.   xl := trunc( XMax / x / 2 );
  493.   yl := trunc( YMax / y / 2);
  494. end;
  495.  
  496. begin {view}
  497.     GetDimensions( XDim, XLength, YDim, Ylength );
  498.     GotDistances := false;
  499.     abort := false;
  500.     repeat
  501.       FillGrid( Grid, OnScreen, Distances, GotDistances, BaseSector, abort );
  502.       if not abort then
  503.         begin
  504.           InitGraphics;
  505.           DrawGrid( Grid, Onscreen );
  506.           readln;
  507.           closeGraph;
  508.           abort := not prompt( 'again? ');
  509.         end; {not abort}
  510.     until abort;
  511. end; {view}